package com.morizhang.merchanmanager.api.monitor.impl;

import com.morizhang.merchanmanager.api.AbstractApiController;
import com.morizhang.merchanmanager.api.dao.AlertDao;
import com.morizhang.merchanmanager.api.dao.CommodityDataDao;
import com.morizhang.merchanmanager.api.dao.CommodityExpireDayDao;
import com.morizhang.merchanmanager.api.dao.CommodityStorageDao;
import com.morizhang.merchanmanager.api.model.AlertModel;
import com.morizhang.merchanmanager.api.model.CommodityExpireModel;
import com.morizhang.merchanmanager.api.model.StockModel;
import com.morizhang.merchanmanager.api.monitor.IMonitor;
import com.morizhang.merchanmanager.api.monitor.MonitorAnnotation;
import com.morizhang.merchanmanager.api.utils.SerialNoGenerator;
import lombok.SneakyThrows;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;

import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

@MonitorAnnotation(name = "ProductTimeMonitor")
public class ProductTimeMonitor implements IMonitor {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractApiController.class);

    @Autowired
    private CommodityStorageDao commodityStorageDao;

    @Autowired
    private CommodityExpireDayDao commodityExpireDayDao;

    @Autowired
    private AlertDao alertDao;

    @Autowired
    private CommodityDataDao commodityDataDao;

    @Autowired
    private Environment environment;

    @SneakyThrows
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        LOGGER.info("Product Time Monitor Called, Checking Stock......");
        List<StockModel> allStock = commodityStorageDao.selectAllCommodityStorage();
        String alertDaysConfig = environment.getProperty("monitor.producttime.alertdays");
        if (alertDaysConfig == null)
            return;
        int alertDays = Integer.parseInt(alertDaysConfig);
        Calendar now = Calendar.getInstance();
        long nowTimeStamp = now.getTimeInMillis();

        Iterator<StockModel> i = allStock.iterator();

        while (i.hasNext()) {
            StockModel stockRecord = i.next();
            String barCode = stockRecord.getBarCode();
            CommodityExpireModel expireModel = commodityExpireDayDao.queryCommodityExpireByBarcode(barCode);
            if (expireModel == null || expireModel.getExpireDays() == null || expireModel.getExpireDays().length() == 0)
                continue;

            String productTime = stockRecord.getProductTime();
            if (productTime == null ||productTime.trim().isEmpty())
                continue;
            long productTimeLong = Long.parseLong(productTime);

            long betweenMillis = nowTimeStamp - productTimeLong;
            int betweenDays = (int) (betweenMillis/86400000);

            if (betweenDays > alertDays)
                continue;
            //触发告警

            //识别商品名称
            String commodityName = commodityDataDao.queryCommodityByBarcode(barCode).getProductName();

            //生成告警识别码
            StringBuilder alertIdentifyCodeBuilder = new StringBuilder();
            alertIdentifyCodeBuilder.append(stockRecord.getBarCode());
            alertIdentifyCodeBuilder.append('-');
            alertIdentifyCodeBuilder.append(stockRecord.getBatchNo());
            alertIdentifyCodeBuilder.append('-');
            alertIdentifyCodeBuilder.append(stockRecord.getAmountNow());
            String commodityIdentifyCode = alertIdentifyCodeBuilder.toString();
            alertIdentifyCodeBuilder.append('-');
            alertIdentifyCodeBuilder.append(betweenDays);
            String alertIdentifyCode = alertIdentifyCodeBuilder.toString();

            //判断是否之前已经对该问题进行过告警
            AlertModel queryParameter = new AlertModel();
            queryParameter.setAlertSource(this.getClass().getName());
            queryParameter.setAlertIdentifyCode(alertIdentifyCode);
            AlertModel existAlert = alertDao.selectByIdentifyCode(queryParameter);

            if (existAlert == null) {
                //使用正则判断是否有过期告警，如果有则将其删除
                String REGEXP = commodityIdentifyCode + '-' + "[0-9]";
                queryParameter.setREGEXP(REGEXP);
                List<AlertModel> existExpireAlert = alertDao.selectByIdentifyCodeUsingREGEXP(queryParameter);
                if (existExpireAlert != null && !existExpireAlert.isEmpty()) {
                    for (AlertModel singleExpireAlert : existExpireAlert) {
                        alertDao.deleteAlert(singleExpireAlert.getSerialNo());
                    }
                }

                AlertModel newAlert = new AlertModel();
                newAlert.setSerialNo(SerialNoGenerator.newSerialNo());
                newAlert.setAlertTitle("保质期告警-" + commodityName + "-" + stockRecord.getBatchNo());
                newAlert.setAlertSource(this.getClass().getName());
                newAlert.setAlertDetail("批次号为 " + stockRecord.getBatchNo() + " 的商品 " + commodityName + "保质期仅剩余 " + betweenDays + " 天，请您及时进行处理!");
                newAlert.setAlertIdentifyCode(alertIdentifyCode);
                newAlert.setAlertTime(Long.toString(now.getTimeInMillis()));
                alertDao.addAlert(newAlert);
                continue;
            }

            existAlert.setAlertTime(Long.toString(now.getTimeInMillis()));
            existAlert.setAlertDetail("批次号为 " + stockRecord.getBatchNo() + " 的商品 " + commodityName + "保质期仅剩余 " + betweenDays + " 天，请您及时进行处理!");
            alertDao.updateAlert(existAlert);
        }
    }
}
